package hzau.service.Impl.SecurityService;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import hzau.constants.ResultConstant;
import hzau.dao.UserDao;
import hzau.pojo.LoginUser;
import hzau.pojo.User;
import hzau.result.Result;
import hzau.service.LoginService;
import hzau.utils.JwtUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@Service
public class LoginServiceImpl implements LoginService {
    final String str="login:";
    @Autowired
    private  AuthenticationManager authenticationManager;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private UserDao userDao;
    @Override
    public Result login(User user) {
        //AuthenticaltionManger authenticate 进行用户认证
        //将用户名和密码封装成authenticationToken对象
        UsernamePasswordAuthenticationToken authenticationToken=new UsernamePasswordAuthenticationToken(user.getUserName(),user.getPassword());
        Authentication authentication = authenticationManager.authenticate(authenticationToken);

        //如果认证没有通过,给出对应的提示
        if(Objects.isNull(authentication)){
            throw new RuntimeException("登录失败");
        }
        //如果认证通过 使用id生成一个jwt,并返回
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        Long id = loginUser.getUser().getId();
        String jwt= JwtUtils.genJwt(id);
        Map<String ,String> map=new HashMap<>();
        map.put("token",jwt);
        map.put("auth",loginUser.getUser().getAuth());
        map.put("url",loginUser.getUser().getPic());
        //把完整的用户信息存入redis userid作为key
        String key=str+id.toString();
        redisTemplate.opsForValue().set(key,loginUser);
        return Result.success(map);
    }

    @Override
    public Result logout() {
        //获取SecurityContextHolder中的用户id
        UsernamePasswordAuthenticationToken authentication =
                (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        Long id = loginUser.getUser().getId();
        //删除redis中的值
     redisTemplate.delete("login:"+id);
        //
        return Result.success("注销成功");
    }

    @Override
    public Result register(String userName, String password) {
        User user=new User();
        BCryptPasswordEncoder passwordEncoder=new BCryptPasswordEncoder();
        String encode = passwordEncoder.encode(password);
        user.setUserName(userName);
        user.setPassword(encode);
        userDao.insert(user);
        LambdaQueryWrapper<User> lqw=new LambdaQueryWrapper<>();
        lqw.eq(User::getUserName,userName).eq(User::getPassword,encode);
        User user1 = userDao.selectOne(lqw);
        return Result.success(user1.getId());

    }

    @Override
    public Result weChatLogin(String wechatId) {
        LambdaQueryWrapper<User> lqw=new LambdaQueryWrapper<>();
        lqw.eq(User::getWechatId,wechatId);
        User user = userDao.selectOne(lqw);
        if(user!=null){
            Long id = user.getId();
            String jwt= JwtUtils.genJwt(id);
            Map<String ,String> map=new HashMap<>();
            map.put("token",jwt);
            map.put("auth",user.getAuth());
            map.put("url",user.getPic());
            //把完整的用户信息存入redis userid作为key
            String key=str+id.toString();
            LoginUser loginUser=new LoginUser(user);
            redisTemplate.opsForValue().set(key,loginUser);
            return Result.success(map);
        }else{
            return Result.error(ResultConstant.NO_SUCH_OPENID_CODE,ResultConstant.NO_SUCH_OPENID);
        }
    }
}
